package net.sourceforge.peertwitter.mbpast;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import net.sourceforge.peertwitter.core.Profile;
import net.sourceforge.peertwitter.core.messaging.TweetMessage;
import net.sourceforge.peertwitter.scamp.Swarm;

import rice.environment.Environment;
import rice.p2p.commonapi.Id;
import rice.p2p.commonapi.Node;

public class MBStorageImpl implements MBStorage {
	private final Map<Id, Replication> replications;
	private Environment env;
	
	public MBStorageImpl(Node owner, Environment env) {
		this.replications = new HashMap<Id, Replication>(1);
		this.env = env;
	}
	
	public void addId(Id id) {
		if (!replications.containsKey(id)) {
			replications.put(id, null);
		}
	}
	
	public void storeReplication(Replication r) {
		replications.put(r.getId(), r);
	}
	
	@Override
	public void storeUpdates(Id author, List<TweetMessage> lastUpdates) {
		createReplicationIfNotExistent(author).setUpdates(lastUpdates);
	}

	@Override
	public void storeProfile(Profile profile) {
		createReplicationIfNotExistent(profile.getId()).setProfile(profile);
	}

	private Replication createReplicationIfNotExistent(Id id) {
		if (!replications.containsKey(id))
			replications.put(id, new ReplicationImpl(new Profile(id), env));
		return replications.get(id);
	}

	@Override
	public void storeSwarmView(Swarm swarm) {
		createReplicationIfNotExistent(swarm.getOwner()).setSwarm(swarm);
	}

	@Override
	public void storeUpdate(TweetMessage tm) {
		createReplicationIfNotExistent(tm.getSender().getId()).addTweet(tm);
	}

	@Override
	public Set<Id> getIds() {
		return new HashSet<Id>(replications.keySet());
	}

	@Override
	public boolean hasReplication(Id id) {
		return replications.containsKey(id);
	}
	
	
	public Replication getReplication(Id id) {
		return replications.get(id);
	}

	@Override
	public ReplicationTimestamp getTimestamp(Id replicaId) {
		if (!hasReplication(replicaId)) {
			throw new RuntimeException("The requested replica is not available: " + replicaId);
		}
		return replications.get(replicaId);
	}

	@Override
	public boolean isConsolidated(Id replicaId) {
		return hasReplication(replicaId) && getReplication(replicaId).isComplete();
	}

}
